package com.iwayin.web.action.user;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.ServletActionContext;
import org.epistem.util.Base64;

import com.iwayin.core.bo.ask.AskBO;
import com.iwayin.core.bo.fans.FansBO;
import com.iwayin.core.bo.follow.FollowBO;
import com.iwayin.core.bo.user.UserBO;
import com.iwayin.core.common.Constants;
import com.iwayin.core.dataobject.AskDO;
import com.iwayin.core.dataobject.FansDO;
import com.iwayin.core.dataobject.FollowDO;
import com.iwayin.core.dataobject.UserDO;
import com.iwayin.core.utils.DateTimeUtil;
import com.iwayin.core.utils.PasswordUtil;
import com.iwayin.core.utils.StringUtil;
import com.iwayin.core.utils.exception.BOException;
import com.iwayin.web.action.BaseAction;
import com.iwayin.web.common.AjaxResult;
import com.iwayin.web.common.CookieUtil;
import com.iwayin.web.common.EmailSender;
import com.iwayin.web.common.FreeMarkerManager;
import com.iwayin.web.common.WebConstants;

public class UserAction extends BaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6522972130845180487L;
	public static final String DEFAULT_PASSWORD = "yoasking";

	private int size;
	private boolean login;
	private UserDO user;
	private UserDO query;
	private String email;
	private String loginName;
	private String nickName;
	private String loginPwd;
	private String realPassword;
	private String newPassword;
	private String birthday;
	private UserBO userBO;
	private String dt;// 激活串
	private String emailHost;
	private Long userId;
	private List<UserDO> userList;
	private List<UserDO> follows;
	private List<UserDO> fans;
	private List<AskDO> asks;
	private AjaxResult ajaxResult;

	private FollowBO followBO;
	private FansBO fansBO;
	private AskBO askBO;

	/**
	 * 注册用户
	 * 
	 * @return
	 */
	public String registUser() {
		user.setOriginalAvatarPath(Constants.DEFAULT_USER_AVATAR_ORIGINAL);
		user.setAvatarPath(Constants.DEFAULT_USER_AVATAR);
		user.setStatus(UserDO.USER_NOT_ACTIVATE_STATUS);
		Long userId = userBO.addUser(user);
		if (userId != null) {
			String[] str = user.getLoginName().split("@");
			if (str[1].contains("hotmail") || str[1].contains("live")) {
				emailHost = "http://" + str[1];
			} else {
				emailHost = "http://mail." + str[1];
			}
			// 发送激活邮件
			EmailSender.send(user.getEmail(), "优问网账户激活邮件", buildActiveMessage(user), "text/html");
		}
		return SUCCESS;
	}

	/**
	 * 重新发送激活邮件
	 * 
	 * @return
	 */
	public String reSendActiveEmail() {
		try {
			UserDO user = userBO.getUserByLoginName(email);
			if (user == null) {
				ajaxResult = AjaxResult.errorResult("账户被回收，请重新注册");
			} else if (user.getStatus().equals(1L)) {
				ajaxResult = AjaxResult.errorResult("账户已经被激活，请直接登陆");
			} else {
				String emailCotent = buildActiveMessage(user);
				EmailSender.send(user.getEmail(), "优问网账户激活邮件", emailCotent, "text/html");
				ajaxResult = AjaxResult.commonResult("激活邮件已经发送到注册邮箱中，请查收");
			}
		} catch (Exception e) {
			ajaxResult = AjaxResult.errorResult(getText("system.error"));
		}
		return SUCCESS;
	}

	/*
	 * 构造激活邮件
	 */
	private String buildActiveMessage(UserDO user) {
		// 激活码：time、email,base64加密
		StringBuilder sb = new StringBuilder();
		String currentDate = DateTimeUtil.getFormatDate(new Date(), DateTimeUtil.TIME_FORMAT_OUT);
		sb.append(user.getLoginName()).append("&").append(currentDate);
		String activeCode = new String(Base64.encode(sb.toString().getBytes()));
		// 邮件内容
		String link = "http://www.yoasking.com/user/activate.action?dt=" + activeCode;
		String msg = user.getNickname() + ",欢迎您成为优问网会员，请点击以下链接激活账户:<br>" + "<a href='" + link + "'>" + link + "</a><br>";
		String sysMsg = "如果点击无效,复制到浏览器也可激活<br>此邮件为系统发送,请勿回复.";

		return msg + sysMsg;
	}

	/**
	 * 用户激活
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String activateUser() {
		try {
			String activeCode = new String(Base64.decode(dt));
			String[] strs = activeCode.split("&");
			UserDO u = userBO.getUserByLoginName(strs[0]);
			// TODO
			if (u == null) {
				return ERROR;
			}
			user = userBO.updateActivateUser(u);
			this.session.put(WebConstants.LOGIN_USER, user);
			CookieUtil.addCookie(ServletActionContext.getResponse(), Constants.COOKIE_USERNAME, user.getNickname());
			CookieUtil.addCookie(ServletActionContext.getResponse(), Constants.COOKIE_PASSWORD, user.getLoginPwd());
		} catch (Exception e) {

		}
		return SUCCESS;
	}

	/**
	 * 用户登录
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String login() {
		// loginName、loginPwd参数校验
		if (StringUtil.isEmpty(loginName)) {
			ajaxResult = AjaxResult.errorResult("用户名为空");
			return SUCCESS;
		}
		if (StringUtil.isEmpty(loginPwd)) {
			ajaxResult = AjaxResult.errorResult("密码为空");
			return SUCCESS;
		}

		UserDO u = null;
		if (loginName.contains("@")) {
			u = userBO.getUserByLoginName(loginName);
		} else {
			u = userBO.getUserByNickName(loginName);
		}
		// 检测用户
		if (u == null) {
			ajaxResult = AjaxResult.errorResult("用户名错误");
			return SUCCESS;
		}
		// 检验密码
		if (PasswordUtil.isPasswordCorrect(u.getLoginPwd(), loginPwd, u.getPwdKey())) {
			if (!u.getStatus().equals(UserDO.USER_ACTIVE_STATUS)) {
				ajaxResult = AjaxResult.errorResult("用户未激活，请激活!");
				Map<String, String> param = new HashMap<String, String>();
				param.put("loginEmail", u.getLoginName());
				ajaxResult.setResultMap(param);
				return SUCCESS;
			}
			this.session.put(WebConstants.LOGIN_USER, u);
			CookieUtil.addCookie(ServletActionContext.getResponse(), Constants.COOKIE_USERNAME, this.getLoginUser().getNickname());
			CookieUtil.addCookie(ServletActionContext.getResponse(), Constants.COOKIE_PASSWORD, this.getLoginUser().getLoginPwd());
			ajaxResult = AjaxResult.commonResult("不要着急哦,精彩马上就来");
		} else {
			ajaxResult = AjaxResult.errorResult("密码错误");
		}
		return SUCCESS;
	}

	/**
	 * 用户登出
	 * 
	 * @return
	 */
	public String logout() {
		this.session.remove(WebConstants.LOGIN_USER);
		CookieUtil.clearCookie(ServletActionContext.getResponse(), Constants.COOKIE_USERNAME);
		CookieUtil.clearCookie(ServletActionContext.getResponse(), Constants.COOKIE_PASSWORD);
		return SUCCESS;
	}

	/**
	 * 检查邮箱是否可用 返回错误：邮箱已经存在，不可用
	 * 
	 * @return
	 */
	public String checkEmail() {
		if (StringUtil.isEmpty(email)) {
			ajaxResult = AjaxResult.errorResult("亲,手下留情哦!");
			return SUCCESS;
		}
		try {
			if (userBO.getUserByEmail(email) == null) {
				// 邮箱未被使用
				ajaxResult = AjaxResult.succResult();
			} else {
				ajaxResult = AjaxResult.errorResult("邮箱已被使用");
			}
		} catch (Exception e) {
			ajaxResult = AjaxResult.errorResult(Constants.DEFAULT_SYSTEM_ERROR_MSG);
		}
		return SUCCESS;
	}

	/**
	 * 主页
	 * 
	 * @return
	 */
	public String home() {
		UserDO loginUser = this.getLoginUser();
		if (loginUser == null) {
			return "unLogin";
		} else {
			return "alreadyLogin";
		}
	}

	/**
	 * 登陆前首页
	 * 
	 * @return
	 */
	public String index() {
		AskDO ask = new AskDO();
		ask.setPerPageSize(12);
		List<AskDO> tempAsks = this.askBO.findNoLoginLastestAsk(ask);
		int gap = 3;
		int end = tempAsks.size();
		int circleCount = end % gap == 0 ? end / gap : end / gap + 1;
		int circle = 0;
		int circleIndex = 0;
		// 0 3 6 9 3(circleIndex-1)+circle-1
		// 1 4 7 10 3(circleIndex-1)+circle-1
		// 2 5 8 11 3(circleIndex-1)+circle-1
		asks = new ArrayList<AskDO>(tempAsks.size());
		for (int i = 0; i < end; i++) {
			circle = asks.size() / circleCount;
			circleIndex = (asks.size() + 1) % circleCount;
			circleIndex = circleIndex==0?circleCount:circleIndex;
			int index = gap * (circleIndex - 1) + circle;
			if(index<end){
				asks.add(tempAsks.get(index));
			}
		}
		return SUCCESS;
	}

	/**
	 * 登陆后首页
	 * 
	 * @return
	 */
	public String loginIndex() {
		user = this.userBO.getUserById(this.getLoginUser().getId());
		return SUCCESS;
	}

	/**
	 * 检查用户名是否可用 返回错误:用户名未被使用，可以使用
	 * 
	 * @return
	 */
	public String checkLoginName() {
		if (StringUtil.isEmpty(loginName)) {
			ajaxResult = AjaxResult.errorResult("亲,手下留情哦!");
			return SUCCESS;
		}
		try {
			if (userBO.getUserByLoginName(loginName) == null) {
				ajaxResult = AjaxResult.succResult();
			} else {
				ajaxResult = AjaxResult.errorResult("电子邮件地址已经被使用");
			}
		} catch (Exception e) {
			ajaxResult = AjaxResult.errorResult(Constants.DEFAULT_SYSTEM_ERROR_MSG);
		}
		return SUCCESS;
	}

	/**
	 * 检查昵称
	 * 
	 * @return
	 */
	public String checkNickname() {
		if (StringUtil.isEmpty(nickName)) {
			ajaxResult = AjaxResult.errorResult("亲,手下留情哦!");
			return SUCCESS;
		}
		try {
			UserDO obj = userBO.getUserByNickName(nickName);
			if (obj == null) {
				ajaxResult = AjaxResult.succResult();
			} else {
				if(userId != null && userId.equals(obj.getId())){
					ajaxResult = AjaxResult.succResult();
				}else{
					ajaxResult = AjaxResult.errorResult("昵称太热，被别人抢走啦，换一个吧");
				}
			}
		} catch (Exception e) {
			ajaxResult = AjaxResult.errorResult(Constants.DEFAULT_SYSTEM_ERROR_MSG);
		}
		return SUCCESS;
	}

	/**
	 * @author zhanglei 修改密码
	 */
	public String updatePassword() {
		try {
			UserDO userDO = (UserDO) this.session.get(WebConstants.LOGIN_USER);
			String passwordKey = PasswordUtil.getRandomOperPassword();// 随机key
			userDO.setPwdKey(passwordKey);
			String encryptPassword = PasswordUtil.getEncyptedOperPassword(this.getNewPassword(), passwordKey);
			userDO.setLoginPwd(encryptPassword);// 加密后密码
			this.userBO.updateUserInfo(userDO);
			ajaxResult = AjaxResult.commonResult("修改成功");
		} catch (Exception e) {
			ajaxResult = AjaxResult.errorResult(Constants.DEFAULT_SYSTEM_ERROR_MSG);
		}
		return SUCCESS;
	}

	/**
	 * 
	 * @param obj
	 * @param inviteId
	 *            //邀请者ID
	 */
	@SuppressWarnings("unused")
	private void sendActivationEmail(UserDO obj, Long inviteId) {
		String currentDate = DateTimeUtil.getFormatDate(new Date(), DateTimeUtil.TIME_FORMAT);
		String lognameParam = Base64.encode((obj.getLoginName() + ";" + currentDate).getBytes());
		Map<String, Object> paraMap = new HashMap<String, Object>();
		FreeMarkerManager.process("", paraMap);
	}

	/**
	 * 
	 * @desc 推荐好友
	 * @param userDO
	 * 
	 */
	public String recommendFriends() {
		UserDO loginUser = this.getLoginUser();
		if (loginUser == null) {
			userList = userBO.recommendFriends(null, size);
		} else {
			userList = userBO.recommendFriends(loginUser.getId(), size);
		}
		return SUCCESS;
	}

	/**
	 * 
	 */
	@SuppressWarnings("unchecked")
	public String updateUserInfo() {
		try {
			Long userId = ((UserDO) this.session.get(WebConstants.LOGIN_USER)).getId();
			if (StringUtil.isNotEmpty(birthday)) {
				user.setBirth(DateTimeUtil.getFormatDate(birthday, DateTimeUtil.DATE_FORMAT));
			}
			user.setId(userId);
			this.userBO.updateUserInfo(user);
			user = this.userBO.getUserById(userId);
			this.session.put(WebConstants.LOGIN_USER, user);
			ajaxResult = AjaxResult.succResult();
		} 
		catch(BOException e){
			ajaxResult = AjaxResult.errorResult(e.getMessage());
		}
		catch (Exception e) {
			ajaxResult = AjaxResult.errorResult("system.error");
		}
		return SUCCESS;
	}
	/**
	 * 为第三方平台用户完善信息
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String reBindAccount(){
		try {
			Long userId = ((UserDO) this.session.get(WebConstants.LOGIN_USER)).getId();
			user.setId(userId);
			this.userBO.updateUserForOpen(user);
			user = this.userBO.getUserById(userId);
			this.session.put(WebConstants.LOGIN_USER, user);
			CookieUtil.addCookie(ServletActionContext.getResponse(), Constants.COOKIE_USERNAME, this.getLoginUser().getNickname());
			CookieUtil.addCookie(ServletActionContext.getResponse(), Constants.COOKIE_PASSWORD, this.getLoginUser().getLoginPwd());
			// 发送激活邮件
			EmailSender.send(user.getEmail(), "优问网账户激活邮件", buildActiveMessage(user), "text/html");
			ajaxResult = AjaxResult.commonResult("优问网向您的邮箱发送了一封激活邮件，为了更好的使用我们提供的服务，请激活您的账户。");
		} catch (Exception e) {
			ajaxResult = AjaxResult.errorResult("system.error");
		}
		return SUCCESS;
	}

	public String userSetting() {
		user = (UserDO) this.session.get(WebConstants.LOGIN_USER);
		if(user.getLoginName() == null){
			return "noLoginName";
		}
		return SUCCESS;
	}

	public String editUserInfo() {
		user = (UserDO) this.session.get(WebConstants.LOGIN_USER);
		return SUCCESS;
	}

	@SuppressWarnings("unchecked")
	public String getUserInfo() {
		UserDO queryUser = this.userBO.getUserByNickName(query.getNickname());
		user = this.userBO.getUserInfo(this.getLoginUser().getId(), queryUser.getId());
		ajaxResult = AjaxResult.succResultAndInitMap();
		ajaxResult.getResultMap().put("userInfo", user);
		return SUCCESS;
	}

	public String toUserAsk() {
		UserDO loginUser = this.getLoginUser();
		user = this.userBO.getUserById(userId);
		getFriendInfo(user);
		if (loginUser == null) {
			AskDO ask = new AskDO();
			ask.setPerPageSize(12);
			ask.setUserId(userId);
			List<AskDO> tempAsks = this.askBO.findNoLoginUserAsk(ask);
			int gap = 3;
			int end = tempAsks.size();
			int circleCount = end % gap == 0 ? end / gap : end / gap + 1;
			int circle = 0;
			int circleIndex = 0;
			// 0 3 6 9 3(circleIndex-1)+circle-1
			// 1 4 7 10 3(circleIndex-1)+circle-1
			// 2 5 8 11 3(circleIndex-1)+circle-1
			asks = new ArrayList<AskDO>(tempAsks.size());
			for (int i = 0; i < end; i++) {
					circle = asks.size() / circleCount;
					circleIndex = (asks.size() + 1) % circleCount;
					circleIndex = circleIndex == 0 ? circleCount : circleIndex;
					int index = gap * (circleIndex - 1) + circle;
					if(index<end){
						asks.add(tempAsks.get(index));
					}
			}
			return "unLogin";
		} else {
			return "alreadyLogin";
		}

	}

	public String toUserFollow() {
		UserDO loginUser = this.getLoginUser();
		user = this.userBO.getUserById(userId);
		getFriendInfo(user);
		if (loginUser == null) {
			return "unLogin";
		} else {
			return "alreadyLogin";
		}
	}

	public String toUserFans() {
		UserDO loginUser = this.getLoginUser();
		user = this.userBO.getUserById(userId);
		getFriendInfo(user);
		if (loginUser == null) {
			return "unLogin";
		} else {
			return "alreadyLogin";
		}
	}

	public void getFriendInfo(UserDO user) {
		FollowDO follow = new FollowDO();
		follow.setUserId(user.getId());
		follow.setPerPageSize(8);
		follows = this.followBO.findFollowList(null, follow);

		FansDO fan = new FansDO();
		fan.setUserId(user.getId());
		fan.setPerPageSize(8);
		fans = this.fansBO.findFansList(null, fan);

		AskDO ask = new AskDO();
		ask.setUserId(user.getId());
		ask.setPerPageSize(8);
		asks = this.askBO.findUserAsks(ask);
	}

	public UserDO getUser() {
		return user;
	}

	public void setUser(UserDO user) {
		this.user = user;
	}

	public UserDO getQuery() {
		return query;
	}

	public void setQuery(UserDO query) {
		this.query = query;
	}

	public List<UserDO> getUserList() {
		return userList;
	}

	public AjaxResult getAjaxResult() {
		return ajaxResult;
	}

	public void setUserBO(UserBO userBO) {
		this.userBO = userBO;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getLoginPwd() {
		return loginPwd;
	}

	public void setLoginPwd(String loginPwd) {
		this.loginPwd = loginPwd;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public boolean isLogin() {
		return login;
	}

	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public String getRealPassword() {
		return realPassword;
	}

	public void setRealPassword(String realPassword) {
		this.realPassword = realPassword;
	}

	public String getNewPassword() {
		return newPassword;
	}

	public void setNewPassword(String newPassword) {
		this.newPassword = newPassword;
	}

	public String getDt() {
		return dt;
	}

	public void setDt(String dt) {
		this.dt = dt;
	}

	public void setFollowBO(FollowBO followBO) {
		this.followBO = followBO;
	}

	public void setFansBO(FansBO fansBO) {
		this.fansBO = fansBO;
	}

	public List<UserDO> getFollows() {
		return follows;
	}

	public void setFollows(List<UserDO> follows) {
		this.follows = follows;
	}

	public List<UserDO> getFans() {
		return fans;
	}

	public void setFans(List<UserDO> fans) {
		this.fans = fans;
	}

	public List<AskDO> getAsks() {
		return asks;
	}

	public void setAsks(List<AskDO> asks) {
		this.asks = asks;
	}

	public void setAskBO(AskBO askBO) {
		this.askBO = askBO;
	}

	public String getNickName() {
		return nickName;
	}

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}

	public String getEmailHost() {
		return emailHost;
	}

	public void setEmailHost(String emailHost) {
		this.emailHost = emailHost;
	}

	public Long getUserId() {
		return userId;
	}

	public void setUserId(Long userId) {
		this.userId = userId;
	}

}
